#include "chess.h"

#include <iostream>

typedef unsigned int INDEX;
typedef int square;

square SqFindKing(square* squares)
{
  return squares[15];
}
square SqFindOne(square* squares, int piece)
{
  return squares[(3*piece)-3];
}
square SqFindFirst(square* squares, int piece)
{
  return squares[(3*piece)-3];
}
square SqFindSecond(square* squares, int piece)
{
  return squares[(3*piece)-2];
}
square SqFindThird(square* squares, int piece)
{
  return squares[(3*piece)-1];
}
//Including a .cpp is bad practice, but the library demands it
#include "egtb/tbindex.cpp"

using namespace std;

int probeBoard(ChessBoard* board)
{
  int counters[10];
  int whiteSquares[16], blackSquares[16];
  int tb;
  int epSquare;
  int index, value;
  int turn = board->minPlayerTurn() ? x_colorBlack : x_colorWhite;
  for(int i = 0; i < 10; i++) counters[i] = 0;
  
  
  //first count and label all the pieces
  for(int i = 0; i < 8; i++)
  {
    for(int j = 0; j < 8; j++)
    {
      int piece = board->getPiece(i, j);
      if(piece == EMPTY) continue;
      if(piece < W_KING)
      {
        whiteSquares[3 * (piece - W_PAWN) + counters[piece - W_PAWN]] = j * 8 + i;
        counters[piece - W_PAWN]++;
        continue;
      }
      if(piece == W_KING)
      {
        whiteSquares[15] = j * 8 + i;
        continue;
      }
      if(piece < B_KING)
      {
        blackSquares[3 * (piece - B_PAWN) + counters[piece - B_PAWN + 5]] = j * 8 + i;
        counters[piece - B_PAWN + 5]++;
        continue;
      }
      if(piece == B_KING)
      {
        blackSquares[15] = j * 8 + i;
        continue;
      }
      cerr << "Found a square that is not empty but has no piece?!" << endl;
    }
  }
  
  //now that we have a count for everything we can probe to see if we have a tablebase loaded
  tb = IDescFindFromCounters(counters);
  if(tb == 0)
  {
    return 0;
  }
  
  epSquare = board->myboard.getEnPassantStatus();
  if(!epSquare) epSquare = 127;
  else
  {
    int col = 8 - (epSquare % 8);
    int row = epSquare / 8;
    if(row == 1) row = 5;
    else row=2;
    epSquare = 8 * col + row;
  }
  
  //now make sure that this position is in the table
  if(!FRegistered(tb, turn))
  {
    return 0;
  }
  
  if(tb > 0)
  {
    index = PfnIndCalc(tb, turn)(whiteSquares, blackSquares, epSquare, 0);
  }
  else //tb < 0, and we need to do some crap the library should take care of for itslef
  {
    index = PfnIndCalc(tb, turn)(blackSquares, whiteSquares, epSquare, 1);
  }
  
  value = L_TbtProbeTable(tb, turn, index);
  
  if(value == bev_broken) return 0; //something bad happened!
  
  if(value > 0) return value;
  return value - 1; //value = 0 for a draw, but 0 is our error code, so we just shift the values down.
}